home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac100% 1998 November
/
MAC100-1998-11.ISO.7z
/
MAC100-1998-11.ISO
/
オンラインソフト定点観測
/
ユーティリティ
/
Mops 3.2.sea
/
Mops 3.2
/
Mops source
/
PPC source
/
cg7
< prev
next >
Wrap
Text File
|
1998-06-22
|
7KB
|
294 lines
:f EXECERR
." attempt to EXECUTE a non-EXECUTEable word"
1 die
;f
(*
This file is only loaded when we're target compiling - it includes
the main interpretation/compilation loop for the native PPC image.
*)
¥ ================================
¥ INTERPRETATION
¥ ================================
(*
In our native code/STC system, interpreting a word is slightly non-trivial.
We provide two types of execution. EXECUTE simply JMPs to
the given cfa. This will work for many words, but not all. For the
general case we provide another execution word EX-GEN (execute general)
which compiles the word in a separate buffer, plants a
jump at the end, then branches to the start. The jump at the end
goes to ChkOK which checks the stack before returning. EX-GEN is
slower than EXECUTE, but will execute anything. For this reason
it is called by INTERPRET. But note, EX-GEN can't be called from an
installed application, since it causes compilation to occur.
*)
: (EX-GEN) { xt opcode compN? ¥ svCDP svNewCDP svExBuff_offs svLeaf?
svMC svMD -- }
CDP -> origCDP ¥ in case of an error during (comp)
CDP -> svCDP leaf? -> svLeaf?
exBuff exBuff_offs + -> svNewCDP
svNewCDP -> CDP
:noname drop
xt
compN? IF opcode (compN) ELSE (comp) THEN
tempObj_framesize
0 -> tempObj_framesize
300 " ;" evaluate ¥ need native PPC ;
-> tempObj_framesize ¥ and can't be any temp objects!
exBuff_offs -> svExBuff_offs ¥ Save old ExBuf offset
CDP svNewCDP - ¥ length of compiled code
++> exBuff_offs ¥ increment ExBuff_offset by this amount
svCDP -> CDP ¥ restore proper CDP
svLeaf? -> leaf? ¥ and leaf? flag
0 -> origCDP ¥ CDP is "normal" again
modCode -> svMC modData -> svMD
compmod
IF modcode_comp_start half_displ_range + -> modCode
moddata_comp_start half_displ_range + -> modData
THEN
( :noname xt ) execute ¥ execute compiled code
svMC -> modCode svMD -> modData ¥ restore module base addr regs
svExBuff_offs -> exBuff_offs ¥ and old exBuf offset
?stack
;
: EX-GEN ( xt -- ) 0 false (ex-gen) ;
: EXN ( xt n -- ) ¥ This is to EX-GEN what (COMPN) is to (COMP). It
¥ has the additional parameter n which is action code for
¥ -> ++> etc.
true (ex-gen) ;
(*
INTERPRET is the interpretation loop. Words from the input stream are
interpreted until the input is exhausted.
*)
forward fNum? ¥ handles a floating point number.
:f fNum? false ;f ¥ will be defined properly when FP loaded
: TRY_NUMBER
fNum? ¥ first check for a floating number
¥ If it returns true, nothing more to do
NIF
number ¥ not FP num - try for ordinary number. Fails if not
state
IF ¥ compiling - compile number as a literal.
postpone literal
THEN ¥ if interpreting, nothing more to do
THEN
;
:f INTERPRET
BEGIN ¥ interpretation loop
?stack
logVec
bl skip-src
>in @ src-len = ?EXIT ¥ out if source exhausted
defined?
dup 0>
IF ¥ it's immediate. As the word may have just been
¥ compiled, we call fix_caches first, to ensure we don't get stale
¥ instructions in the icache. We use EXECUTE rather than EX-GEN which
¥ would have been a lot slower, and would block optimization of any code
¥ being compiled (this might be an immediate word during compilation,
¥ like IF). But note, we must ensure immediate words can be directly
¥ called!
drop
¥ dup 2- 512 fix_caches
execute
ELSE
IF ¥ found - not immediate - but what is STATE ?
state
NIF ¥ Interpretation. We execute the word via
¥ EX-GEN, since all words are possible here.
ex-gen
ELSE
(comp)
THEN
ELSE ¥ word not found. Check for a number.
try_number ¥ fails if no number
THEN
THEN
AGAIN
;f
: INTRP1 ( -- ?? ) ¥ Interprets one word/number from the input stream.
defined?
IF ex-gen
ELSE number
THEN
;
: OK & > emit ;
0 valuex quitTest?
:f QUIT
0 -> state ¥ i.e. postpone [
quitVec
BEGIN
?DP RP0 RP!
¥ quitTest? if dbgr then
state
IF 3 spaces
ELSE OK
THEN
query
interpret
AGAIN
;f
:f SETUP_CG
branchType >type: branch_instrn
deep_classinit: cstk
deep_classinit: cstk2
deep_classinit: cstk2_orig
deep_classinit: cstk_temp
deep_classinit: fcstk
deep_classinit: fcstk2
deep_classinit: gprs
deep_classinit: fprs
deep_classinit: crs
gprRef 10 init: GPRs
fprRef 13 init: FPRs
CRref 7 init: CRs
gprRef 10 init: stored_GPRs
fprRef 10 init: stored_FPRs
classinit: theOD
classinit: tmpOD
classinit: valOD
classinit: storedOD
allocate_reserved_regs
CDP -> last_colon_defn ¥ used by (b&d)
classinit: const_data
new: eq_ranges ¥ see cg3
new: const_data new: sv_const_data
;f
¥ Note: we make IMMEDIATE immediate, so we can put it at the start of
¥ a definition if we want to - aids readability if the defn is longish.
: IMMEDIATE
$ 40 latest cset ; ppc_only
: IMMED
$ 40 latest cset ; ppc_immediate
¥ USES_CTR is used like IMMEDIATE, and indicates that the defn just
¥ compiled uses the count register (which will disallow DO loops
¥ calling that defn from using the count reg as the loop counter).
¥ This is normally handled automatically, but for code definitions
¥ this word may be useful.
: USES_CTR
$ 40 latest name> cset ; ppc_immediate
: DB
$ 81820008 code, ¥ lwz r12, $8(r2/TOC)
$ 818C0000 code, ¥ lwz r12, (r12)
$ 7D8903A6 code, ¥ mtspr CTR, r12
$ 7C6B1B78 code, ¥ or r11, r3, r3
$ 7D8802A6 code, ¥ mfspr r12, LR
$ 9591FFFC code, ¥ stwu r12, $-4(r17/RP)
$ 4E800421 code, ¥ bctrl
$ 81910000 code, ¥ lwz r12, (r17/RP)
$ 3A310004 code, ¥ addi r17/RP, r17/RP, 4 $4
$ 7D8803A6 code, ¥ mtspr LR, r12
$ 7D635B78 code, ¥ or r3, r11, r11
CDP -> backstop_CDP ¥ it's confusing if loads get hoisted here
; ppc_immediate
: DBX
0 code,
; ppc_immediate
¥ We also have to unresolve all SysCalls and mark all modules as
¥ absent at initial startup. This allows us to not do it when
¥ we write out a PEF, so that we can continue running.
forward MOD?
:f mod? false ;f ¥ dummy - the real defn is in Modules.
: (UNRES) { xt dummy ¥ modAddr -- }
xt 2- w@ $ BF01 = ¥ is it a syscall or extern?
IF nilP xt 6 + @abs ! EXIT THEN
xt mod? NIF drop EXIT THEN
>obj -> modAddr
nilH modAddr !
;
: UNRESOLVE_EVERYTHING { ¥ ^ST -- }
['] (unres) 0 trav ¥ fix syscalls and modules
¥ now we set all assigned segments to absent
max_segs 2
DO i 8 * segTable + -> ^ST
^ST @
IF ¥ it's assigned - set its base addr to nil
nilP ^ST 4+ !
THEN
LOOP
;
: INIT1 ¥ our initial initialization word.
unresolve_everything
LB_cache 512 erase
instld? NIF setup_cg THEN
filinit
;
:f RUN
init1
['] clFiles -> abortvec ¥ can't interpret ' yet, so we set up
¥ abortvec here at the start of execution
cr ." This is the initial PowerMops nucleus. Type"
cr ." // ppc1.ld"
cr ." to continue building the full system." cr
QUIT
;f